package com.whty.zdxt.multimedia.util;

import com.whty.zdxt.multimedia.attribute.CropAttributes;
import com.whty.zdxt.multimedia.attribute.ResizeAttributes;
import com.whty.zdxt.multimedia.enumeration.Suffix;

/**
 * @author GuoNanLin
 * @date 2020-10-30
 */
public class ImageMagickUtils {

    /**
     * ImageMagick命令magick,需设置magick环境变量
     */
    private static final String MAGICK = "magick";

    /**
     * 图片裁切 并 修改分辨率
     *
     * @param tempDirectory    临时文件目录
     * @param inputFileName    输入文件名
     * @param cropAttributes   裁切参数
     * @param resizeAttributes 修改分辨率参数
     * @param outputFileSuffix 输出文件后缀名
     * @return 输出文件名
     */
    public String cropAndResize(String tempDirectory, String inputFileName, CropAttributes cropAttributes, ResizeAttributes resizeAttributes, Suffix outputFileSuffix) {

        if (!FileUtils.checkFileName(inputFileName)) {
            throw new RuntimeException("输入文件名格式错误");
        }

        // 设置输出文件后缀及名称
        String suffix = null;
        if (outputFileSuffix == null) {
            suffix = FileUtils.getSuffix(inputFileName);
        } else {
            suffix = outputFileSuffix.getCode();
        }
        String outputFileName = FileUtils.createFileName(suffix);

        // 拼接命令
        StringBuilder command = new StringBuilder();
        command.append(MAGICK);
        command.append(" ");

        command.append(FileUtils.getFilePath(tempDirectory, inputFileName));
        command.append(" ");

        command.append("-background white -flatten ");

        // 设置裁切参数
        if (cropAttributes != null) {
            Integer width = cropAttributes.getWidth();
            Integer height = cropAttributes.getHeight();
            Integer leftOffset = cropAttributes.getLeftOffset();
            Integer topOffset = cropAttributes.getTopOffset();
            if (width == null || height == null || leftOffset == null || topOffset == null) {
                throw new RuntimeException("CropAttributes缺失必要参数");
            }

            command.append("-crop");
            command.append(" ");

            // 拼接裁切参数 例：3000x1200+1000+500
            command.append(String.format("%sx%s%s%s", width, height, leftOffset < 0 ? leftOffset : "+" + leftOffset, topOffset < 0 ? topOffset : "+" + topOffset));
            command.append(" ");
        }

        // 设置修改分辨率参数
        if (resizeAttributes != null) {
            Integer width = resizeAttributes.getWidth();
            Integer height = resizeAttributes.getHeight();
            if (width == null && height == null) {
                throw new RuntimeException("ResizeAttributes缺失必要参数");
            }
            command.append("-resize");
            command.append(" ");

            if (width != null) {
                command.append(width);
            }
            if (height != null) {
                command.append("x");
                command.append(height);
            }
            command.append(">");
            command.append(" ");

            // 设置输出质量参数
            if (resizeAttributes.getQuality() != null) {
                command.append("-quality ");
                command.append(resizeAttributes.getQuality());
                command.append(" ");
            }
        }

        // 如果输出为.webp，则设置为无损格式
        if (Suffix.WEBP_LOSSLESS == outputFileSuffix) {
            command.append("-define webp:lossless=true ");
        }

        // 设置输出文件名
        command.append(FileUtils.getFilePath(tempDirectory, outputFileName));

        RuntimeUtils.execSF(command.toString());

        return outputFileName;
    }

    /**
     * 图片裁切 并 修改分辨率
     *
     * @param tempDirectory    临时文件目录
     * @param inputFileName    输入文件名
     * @param cropAttributes   裁切参数
     * @param resizeAttributes 修改分辨率参数
     * @return 输出文件名
     */
    public String cropAndResize(String tempDirectory, String inputFileName, CropAttributes cropAttributes, ResizeAttributes resizeAttributes) {
        return this.cropAndResize(tempDirectory, inputFileName, cropAttributes, resizeAttributes, null);
    }

    /**
     * 图片裁切
     *
     * @param tempDirectory    临时文件目录
     * @param inputFileName    输入文件名
     * @param cropAttributes   裁切参数
     * @param outputFileSuffix 输出文件后缀名
     * @return 输出文件名
     */
    public String crop(String tempDirectory, String inputFileName, CropAttributes cropAttributes, Suffix outputFileSuffix) {
        return this.cropAndResize(tempDirectory, inputFileName, cropAttributes, null, outputFileSuffix);
    }

    /**
     * 图片裁切
     *
     * @param tempDirectory  临时文件目录
     * @param inputFileName  输入文件名
     * @param cropAttributes 裁切参数
     * @return 输出文件名
     */
    public String crop(String tempDirectory, String inputFileName, CropAttributes cropAttributes) {
        return this.cropAndResize(tempDirectory, inputFileName, cropAttributes, null, null);
    }


    /**
     * 图片分辨率修改
     *
     * @param tempDirectory    临时文件目录
     * @param inputFileName    输入文件名
     * @param resizeAttributes 分辨率属性
     * @param outputFileSuffix 输出文件后缀名
     * @return 输入文件名
     */
    public String resize(String tempDirectory, String inputFileName, ResizeAttributes resizeAttributes, Suffix outputFileSuffix) {
        return this.cropAndResize(tempDirectory, inputFileName, null, resizeAttributes, outputFileSuffix);
    }

    /**
     * 图片分辨率修改
     *
     * @param tempDirectory    临时文件目录
     * @param inputFileName    输入文件名
     * @param resizeAttributes 分辨率属性
     * @return 输入文件名
     */
    public String resize(String tempDirectory, String inputFileName, ResizeAttributes resizeAttributes) {
        return this.cropAndResize(tempDirectory, inputFileName, null, resizeAttributes, null);
    }


}
